# -*- coding: utf-8 -*-
'''
    Created on 2012-09-04
    @author: feiwang
'''
import Image
import ImageDraw
import ImageFont
import logging
import os

_logger = logging.getLogger()

def ensure_unicode(str1):
    '''
        我们所关注的encoding为: utf8和unicode, ensure_utf8在这种前提下能正常工作 
    '''
    if isinstance(str1, unicode):
        return str1
    else:
        return str1.decode('utf-8')

def is_alnum(char):
    '''
        判断是否为数字或字母
    '''
    ## a-z
    if char >= 97 and char <= 122:
        return True
    ## A-Z
    if char >= 65 and char <= 90:
        return True
    ## 0-9
    if char >= 48 and char <= 57:
        return True
    
    return False

def get_next_word(text, start, text_len):
    '''
       获取下一个词
       1. 如果是英文或数字，则返回整个word
       2. 其他则单个单个返回
    '''
    if start >= len:
        return (None, 0)
        
    idx = start
    while idx < text_len:
        if is_alnum(ord(text[idx])):
            idx += 1
        else:
            if idx == start: ## 第一个字符就不是字母
                return (text[idx], idx + 1)
            else:
                ## 从[start:idx]都是一个word
                return (text[start:idx], idx)
    return (text[start:idx], idx)

def get_default_font(font_size):
    '''
       获取默认的字体:
    '''
    ## os.path.join(settings._HOME_DIR, "conf/simhei.ttf")
    font_path = None
    font = ImageFont.truetype(font_path, font_size)
    return font


class SimpleStyledText(object):
    def __init__(self, text, text_color, font, line_height, image_width, margin=(0, 0, 0, 0)):
        '''
            @param text 待render的文本
            @param text_color 文本的颜色
            @param font 使用的字体（包含字体的样式以及大小)
            @param line_height 行高
            @param image_width 目标图片的宽度
            @param margin文本render时的边距的处理
        '''
        self.text = ensure_unicode(text)
        self.text_color = text_color
        self.font = font
        self.line_height = line_height
        self.margin = margin
        self.image_width = image_width
        self.content_width = image_width - margin[1] - margin[3]
        self.wraptext = []
    
    def layout_text(self):
        '''
            返回Layout之后lines
        '''
        if not self.wraptext:
            ## 分析每一个unicode
            text_len = len(self.text)
            
            wraptext = []
            next_idx = 0
            current_line = None
            while next_idx < text_len:
                word, next_idx = get_next_word(self.text, next_idx, text_len) 
                if not word:
                    break
                
                #print "Word: ", word
        
                ## 一行自然结束
                if word == "\n":
                    if current_line is None:
                        ## 发现空行
                        wraptext.append(u"")
                    else:
                        wraptext.append(current_line)
                        current_line = None
                else:
                    tmp_line = (current_line or u"") + word
                    line_size = self.font.getsize(tmp_line)
                    
                    ## 如果宽度超过限制，则换行
                    if line_size[0] > self.content_width:
                        if current_line is None:
                            ## 表明: word太长
                            wraptext.append(word)
                        else:
                            wraptext.append(current_line)
                            current_line = word
                    else:
                        ## 没有超过限制，则更新current_line
                        current_line = tmp_line
                        
            if current_line:
                wraptext.append(current_line)
            
            self.wraptext = wraptext;
        return self.wraptext;
    
    def draw_warped_text(self, image_draw, offset_y):
        '''
           wraped_text 由layout_text生成
        '''
        offset_y += self.margin[0]
        for num, text in enumerate(self.layout_text()):
            pos = (self.margin[3], self.line_height * num + offset_y)
            image_draw.text(pos, text, font = self.font, fill = self.text_color)
        
        return offset_y + len(self.layout_text()) * self.line_height + self.margin[2]

    def get_block_height(self):
        '''
           返回当前Block的高度
        '''
        return len(self.layout_text()) * self.line_height + self.margin[0] + self.margin[2]
    
def multi_format_text_2_image(styled_texts, background_color="#FFFFFF"):
    '''
        @param styled_text: list of [text, color, font, line-height, margin(top, right, bottom, left)]
        @param 
    '''
    if isinstance(styled_texts, SimpleStyledText):
        styled_texts = [styled_texts]
    
    if not styled_texts:
        return None

    ## 计算所有的Block的高度
    total_height = 0
    for styled_text in styled_texts:
        total_height += styled_text.get_block_height()
    
    # Draw picture
    image = Image.new("RGB", (styled_texts[0].image_width, total_height), background_color)
    image_draw = ImageDraw.Draw(image)
    
    ## 绘制每一个Block
    offset_y = 0
    for styled_text in styled_texts:
        offset_y = styled_text.draw_warped_text(image_draw, offset_y)
 
    return image;

    
def text_2_image(text, image_width, font_size, line_height, text_color="#000000", padding=(10, 25, 10, 25)):
    '''
        将text转换成为image, 输入的参数为:
        @param image_width: 最终图片的宽度
        @param font_size: 文字的大小
        @param line_height: 每行的高度
        @param text_color: 文字的颜色, 格式为: "#RRGGBB", 默认为"#000000"
        @param padding = (top, right, bottom, left), 默认为: (10, 25, 10, 25)
        
        @return 返回的格式为Image, 可以调用 image.show()查看图片，可以调用image.save(path)来保存图片
    '''
    text = ensure_unicode(text)
    
    styled_text = SimpleStyledText(
            text = text,
            text_color = text_color,
            font = get_default_font(font_size),
            line_height = line_height,
            image_width = image_width,
            margin = padding,
    )
    return multi_format_text_2_image(styled_text)